<?php
abstract class system_view_helper_placeholder_container_standalone extends system_view_helper_abstract implements IteratorAggregate, Countable, ArrayAccess {
	/**
	 *
	 * @var Zend_View_Helper_Placeholder_Container_Abstract
	 */
	protected static $_container;
	
	/**
	 * Registry key under which container registers itself
	 * 
	 * @var string
	 */
	protected $_key;
	
	/**
	 * Flag wheter to automatically escape output, must also be
	 * enforced in the child class if __toString/toString is overriden
	 * 
	 * @var book
	 */
	protected $_autoEscape = true;
	
	/**
	 * Constructor
	 *
	 * @return void
	 */
	public function __construct() {
		$this->setContainer(new system_view_helper_placeholder_container());
	}
	
	/**
	 * Set whether or not auto escaping should be used
	 *
	 * @param bool $autoEscape
	 *        	whether or not to auto escape output
	 * @return Zend_View_Helper_Placeholder_Container_Standalone
	 */
	public function setAutoEscape($autoEscape = true) {
		$this->_autoEscape = ($autoEscape) ? true : false;
		return $this;
	}
	
	/**
	 * Return whether autoEscaping is enabled or disabled
	 *
	 * return bool
	 */
	public function getAutoEscape() {
		return $this->_autoEscape;
	}
	
	/**
	 * Escape a string
	 *
	 * @param string $string        	
	 * @return string
	 */
	protected function _escape($string) {
		$enc = 'UTF-8';
		if($this->viewinstanceofsystem_view_interface && method_exists($this->view, 'getEncoding')) {
			$enc = $this->view->getEncoding();
		}
		
		return htmlspecialchars((string) $string, ENT_COMPAT, $enc);
	}
	
	/**
	 * Set container on which to operate
	 *
	 * @param Zend_View_Helper_Placeholder_Container_Abstract $container        	
	 * @return Zend_View_Helper_Placeholder_Container_Standalone
	 */
	public function setContainer(system_view_helper_placeholder_container_abstract $container) {
		self::$_container[$this->_key] = $container;
		return $this;
	}
	
	/**
	 * Retrieve placeholder container
	 *
	 * @return Zend_View_Helper_Placeholder_Container_Abstract
	 */
	public function getContainer() {
		return self::$_container[$this->_key];
	}
	
	/**
	 * Overloading: set property value
	 *
	 * @param string $key        	
	 * @param mixed $value        	
	 * @return void
	 */
	public function __set($key, $value) {
		$container = $this->getContainer();
		$container[$key] = $value;
	}
	
	/**
	 * Overloading: retrieve property
	 *
	 * @param string $key        	
	 * @return mixed
	 */
	public function __get($key) {
		$container = $this->getContainer();
		if(isset($container[$key])) {
			return $container[$key];
		}
		
		return null;
	}
	
	/**
	 * Overloading: check if property is set
	 *
	 * @param string $key        	
	 * @return bool
	 */
	public function __isset($key) {
		$container = $this->getContainer();
		return isset($container[$key]);
	}
	
	/**
	 * Overloading: unset property
	 *
	 * @param string $key        	
	 * @return void
	 */
	public function __unset($key) {
		$container = $this->getContainer();
		if(isset($container[$key])) {
			unset($container[$key]);
		}
	}
	
	/**
	 * Overload
	 *
	 * Proxy to container methods
	 *
	 * @param string $method        	
	 * @param array $args        	
	 * @return mixed
	 */
	public function __call($method, $args) {
		$container = $this->getContainer();
		if(method_exists($container, $method)) {
			$return = call_user_func_array(array($container, $method), $args);
			if($return === $container) {
				// If the container is returned, we really want the current
				// object
				return $this;
			}
			return $return;
		}
		
		$e = new system_view_exception('Method "' . $method . '" does not exist');
		$e->setView($this->view);
		throw $e;
	}
	
	/**
	 * String representation
	 *
	 * @return string
	 */
	public function toString() {
		return $this->getContainer()->toString();
	}
	
	/**
	 * Cast to string representation
	 *
	 * @return string
	 */
	public function __toString() {
		return $this->toString();
	}
	
	/**
	 * Countable
	 *
	 * @return int
	 */
	public function count() {
		$container = $this->getContainer();
		return count($container);
	}
	
	/**
	 * ArrayAccess: offsetExists
	 *
	 * @param string|int $offset        	
	 * @return bool
	 */
	public function offsetExists($offset) {
		return $this->getContainer()->offsetExists($offset);
	}
	
	/**
	 * ArrayAccess: offsetGet
	 *
	 * @param string|int $offset        	
	 * @return mixed
	 */
	public function offsetGet($offset) {
		return $this->getContainer()->offsetGet($offset);
	}
	
	/**
	 * ArrayAccess: offsetSet
	 *
	 * @param string|int $offset        	
	 * @param mixed $value        	
	 * @return void
	 */
	public function offsetSet($offset, $value) {
		return $this->getContainer()->offsetSet($offset, $value);
	}
	
	/**
	 * ArrayAccess: offsetUnset
	 *
	 * @param string|int $offset        	
	 * @return void
	 */
	public function offsetUnset($offset) {
		return $this->getContainer()->offsetUnset($offset);
	}
	
	/**
	 * IteratorAggregate: get Iterator
	 *
	 * @return Iterator
	 */
	public function getIterator() {
		return $this->getContainer()->getIterator();
	}
}